package DatabaseCommands;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.sql.DataSource;

/**
 * Create a class to organize the information need to form a connection to a
 * database. Have the class able to use both the DriverManager method of making
 * a connection and the newer DataSource method.
 * 
 * @author cdgira
 * 
 */
public class DatabaseInfo{

	private static DatabaseInfo Instance=null;
    protected String m_databaseName=null;
    protected String m_loginName=null;
    protected String m_password=null;
    public String DatabaseName;
    public String DatabaseUserName;
    protected List<String> Tables;
    public Table CurrentTable;
    
    
    
    /**
     * Alternative way to store the connect information to the database.
     */
    protected DataSource m_dataSource = null;

    /**
     * The actual connection to the database.
     */
    protected Connection DatabaseConnection = null;

    
    /**
     * Used to create a DatabaseInfo instance that connects using
     * the name, login, and password information stored as Strings.
     * @param name
     * @param login
     * @param pass
     */
    
    protected DatabaseInfo(){
		
	}


    public void SetInfo(String name,String DatabaseAddress,String login,String pass,int Port){
    	DatabaseName=name;
    	DatabaseUserName=login;
    	m_databaseName="jdbc:mysql://"+DatabaseAddress+":"+Port+"/"+login+"?connectTimeout=1000";
    	m_loginName=login;
    	m_password=pass;
    }
    
    
    public DatabaseInfo(String name,String login,String pass){
    	m_databaseName=name;
    	m_loginName=login;
    	m_password=pass;
    }
    
    
    public String GetDatabaseName(){
    	return m_databaseName;
    }

    /**
     * Used to create a DatabaseInfo instance for connecting to 
     * a database that uses a DataSource to store all the information.
     * @param dataSource
     */
	public DatabaseInfo(DataSource dataSource){
		m_dataSource=dataSource;
	}

	
	public static DatabaseInfo getInstance(){
		if(Instance==null){
			Instance=new DatabaseInfo();
		}
		return Instance;
	}
	
	
    /**
     * Returns true if connected to the database, false
     * otherwise.
     * @return
     */
	public boolean CheckConnection(){
		boolean Connected=false;
		if(DatabaseConnection!=null){
			Connected=true;
		}
		return Connected;
	}

    
    /**
     * If there is no connection to the database it will create one.
     * If there is a connection already established it will return
     * that connection.
     */
	public void makeConnection() throws Exception{
		if(this.CheckConnection()){
			if(DatabaseConnection.isClosed()){
				if(m_dataSource!=null){
					DatabaseConnection=m_dataSource.getConnection();
				}else if(m_loginName!=null){
					DatabaseConnection=DriverManager.getConnection(m_databaseName,m_loginName,m_password);
				}else{
					DatabaseConnection=DriverManager.getConnection(m_databaseName);
				}
			}
		}else{
			if(m_dataSource!=null){
				DatabaseConnection=m_dataSource.getConnection();
			}else if(m_loginName!=null){
				DatabaseConnection=DriverManager.getConnection(m_databaseName,m_loginName,m_password);
			}else{
				DatabaseConnection=DriverManager.getConnection(m_databaseName);
			}
		}
	}
	
	
	public void SetTables(){
		Tables=new ArrayList<String>();
		try{
			ResultSet Results=DatabaseConnection.getMetaData().getTables(null,null,"%",null);
			while(Results.next()){
				Tables.add(Results.getString(3));
			}
		}catch(Exception E){}
	}
	
	
	public void SetTable(String Table){
		try{
			CurrentTable=new Table(Table,DatabaseConnection);
		}catch(Exception E){}
	}
	
	
	public void PrintTable() throws SQLException{
		CurrentTable.PrintTable();
	}
	
	
	public List<String> GetTables(){
		SetTables();
		return Tables;
	}
	
	
	public boolean ConnectToDataBase() throws Exception{
		makeConnection();
		if(CheckConnection()){
			SetTables();
		}
		return true;
	}
    
	
	public Connection GetConnection(){
		return DatabaseConnection;
	}
	
    /**
     * Closes the connection to the database.
     * @throws SQLException
     */
	public void closeConnection() throws SQLException{
		if(this.CheckConnection()){
			DatabaseConnection.close();
		}
	}

}
